package com.example.system.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.starter.security.annotation.PreInnerAuthorize;
import com.example.starter.util.Response;
import com.example.starter.webmvc.valid.CreateValid;
import com.example.starter.webmvc.valid.UpdateValid;
import com.example.system.api.UserApi;
import com.example.system.constant.PM;
import com.example.system.dto.UserDto;
import com.example.system.dto.UserInfo;
import com.example.system.dto.UserParam;
import com.example.system.entity.User;
import com.example.system.service.IUserService;
import com.example.system.vo.UserVo;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * @author 王令
 * @since 2022/12/10
 */
@RequestMapping("/user")
@RequiredArgsConstructor
@RestController
public class UserController implements UserApi {

    private final IUserService service;

    @PreAuthorize("hasAuthority('"+ PM.SYS_USER_WRITE +"')")
    @PostMapping
    public Response<Boolean> create(@RequestBody @Validated(CreateValid.class) UserDto userDto) {
        service.create(userDto);
        return Response.ok();
    }

    @PreAuthorize("hasAuthority('"+ PM.SYS_USER_WRITE +"')")
    @PutMapping
    public Response<Boolean> update(@RequestBody @Validated(UpdateValid.class) UserDto userDto) {
        service.update(userDto);
        return Response.ok();
    }

    @PreAuthorize("hasAuthority('"+ PM.SYS_USER_WRITE +"')")
    @DeleteMapping("/{id}")
    public Response<Boolean> deleteById(@PathVariable("id") Long id) {
        service.removeById(id);
        return Response.ok();
    }

    @PreAuthorize("hasAuthority('"+ PM.SYS_USER_READ +"')")
    @GetMapping("/{id}")
    public Response<UserVo> findById(@PathVariable("id") Long id) {
        return Response.ok(service.findUserVoById(id));
    }

    @PreInnerAuthorize
    @Override
    public Response<UserInfo> loadByUsername(String username) {
        User user = service.getOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, username));
        return Response.ok(service.findUserInfoByUser(user));
    }

    @PreInnerAuthorize
    @Override
    public Response<UserInfo> loadByMobilePhone(String phone) {
        User user = service.getOne(Wrappers.<User>lambdaQuery().eq(User::getPhone, phone));
        return Response.ok(service.findUserInfoByUser(user));
    }

    @PreAuthorize("hasAuthority('"+ PM.SYS_USER_READ +"')")
    @GetMapping("/pagination")
    public Response<Page<UserVo>> listWithPagination(Pageable pageable, UserParam param) {
        return Response.ok(service.listWithPagination(pageable, param));
    }
}
